<?php
ini_set('memory_limit', '1G');
set_time_limit(0);
header('Content-type:text/html;charset=utf8;');
if(strtok(PHP_VERSION, '.') < 7){
    exit('需要php7+版本');
}

// ----------------------------
// 分析nginx访问日志
// ----------------------------
// 月份（短英文对应数字）
$monthMap = array(
    'Jan'=>'01','Feb'=>'02','Mar'=>'03','Apr'=>'04','May'=>'05','Jun'=>'06',
    'Jul'=>'07','Aug'=>'08','Sep'=>'09','Oct'=>'10','Nov'=>'11','Dec'=>'12',
);
// 排除匹配的字符串
$pathExcludeArr = [
    'a=uploadingFiles', 'a=putShelves', '/h5/index.php', '/robots.txt',
    '.css', '.js', 'favicon.ico', '.png', '.gif',
];

// 时间分组格式
$timeFormat = 'H';
// 条件默认值
$cond = array(
    'ip' => "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",
    'path' => ".*?",
);
$sTime = '';
$eTime = '';

// 输入条件
$type = empty($_GET['type']) ? 'dkw' : $_GET['type'];
!empty($_GET['file_name']) && $cond['file_name'] = $_GET['file_name'];
!empty($_GET['ip']) && $cond['ip'] = preg_quote($_GET['ip']);
!empty($_GET['path']) && $cond['path'] = preg_quote(urldecode($_GET['path']));
$cond['start_time'] = i('start_time');
$cond['end_time'] = i('end_time');
if(!empty($cond['start_time'])){
    $cond['start_time'] = str_replace(' ', ':', $cond['start_time']);
    $cond['start_time'] .= strpos($cond['start_time'], ':') === false ? ':0' : '';
    $cond['start_time'] = strtotime($cond['start_time']);
    $sTime = date('H:i:s', $cond['start_time']);
}
if(!empty($cond['end_time'])){
    $cond['end_time'] = str_replace(' ', ':', $cond['end_time']);
    $cond['end_time'] .= strpos($cond['end_time'], ':') === false ? ':59' : '';
    $cond['end_time'] = strtotime($cond['end_time']);
    $eTime = date('H:i:s', $cond['end_time']);
}
// 查1个小时内，时间按分钟分隔
if(
    (!empty($sTime) && !empty($eTime))
    && $cond['end_time'] - $cond['start_time'] <= 3600
){
    $timeFormat = 'i';
}

// 日期
preg_match('/(\d{4}-\d{2}-\d{2})\./', $cond['file_name'], $dateMatch);
$nowDate = $dateMatch[1];

// 初始化结果
$pv = 0; // 总条数
$uv = 0; // 独立ip条数
$ipCount = array(); // ip分组汇总
$ipCountData = array(); // ip分组汇总的路径数据
$pathCount = array(); // 执行路径分组汇总
$pathCountData = array(); // 执行路径分组的ip数据
$timeCount = array(); // 分钟分组汇总
$timeCountData = array(); // 分钟分组汇总的ip、路径数据
$runtimeCount = array(); // 执行秒数分组汇总
$runtimeCountData = array(); // 执行秒数分组汇总的ip，路径数据

$str = '';
$i = 0;
// 访问日志路径
// $file = "D:\phpstudy_pro\WWW\pc\dkw\\test.log";
$fileName = $cond['file_name'];
$file = sysPath($fileName); // ./log/https-gamebox.api.gzzy128.com-2025-07-24.log
// $str = file_get_contents($file);
if(!is_file($file)){
    exit("file empty: '{$file}'");
}
$fileSize = round(filesize($file) / 1024 / 1024, 3); // MB
// 分批处理
$handle = fopen($file, 'rb');
if (!$handle) {
    exit("Cannot open file: {$file}");
}
while (($line = fgets($handle)) !== false) {
    // 排除
    if(!empty($sTime) || !empty($eTime)){
        preg_match('/:(\d{2}:\d{2}:\d{2}) .*?/', $line, $m);
        if(!empty($sTime) && $m[1] < $sTime){
            continue;
        }
        if(!empty($eTime) && $eTime < $m[1]){
            continue;
        }
    }
    if(!empty($_GET['ip']) && strpos($line, $_GET['ip']) === false){
        continue;
    }
    if(!empty($_GET['path']) && strpos($line, $_GET['path']) === false){
        continue;
    }
    foreach ($pathExcludeArr as $v) {
        if(strpos($line, $v) !== false){
            continue 2;
        }
    }

    $str .= $line;
    $i++;
    if ($i === 1000) {
        // var_dump($str);die;
        calculate($str);
        $str = '';
        $i = 0;
        // break;
    }
}
// 尾部不足 1 万行
if ($str) {
    calculate($str);
}
fclose($handle);


arsort($ipCount);
krsort($runtimeCount);
$uv = count($ipCount);

// ip分组（pv倒序，前20条，统计平均执行时长）
descArr($ipCount, 'pv');
$ipCount = array_slice($ipCount, 0, 50);
$ipCount = array_map(
    function ($v) {
        // 统计平均执行时长
        $v['rt_avg'] = $v['pv'] ? round($v['rt'] / $v['pv'], 5) : 0;
        // descArr($v['datetime'], 'pv');
        // $v['datetime'] = array_slice($v['datetime'], 0, 5);
        // $v['datetime'] = array_map(
        //     function ($vv) {
        //         // 统计平均执行时长
        //         $vv['rt_avg'] = $vv['pv'] ? round($vv['rt'] / $vv['pv'], 5) : 0;
        //         return $vv;
        //     },
        //     $v['datetime']
        // );
        return $v;
    },
    $ipCount
);
// 路径分组（统计平均执行时长，rt_avg倒序，前20条）
$pathCount = array_map(
    function ($v) {
        // 统计平均执行时长
        $v['rt_avg'] = $v['pv'] ? round($v['rt'] / $v['pv'], 5) : 0;
        // descArr($v['datetime'], 'pv');
        // $v['datetime'] = array_slice($v['datetime'], 0, 5);
        // $v['datetime'] = array_map(
        //     function ($vv) {
        //         // 统计平均执行时长
        //         $vv['rt_avg'] = $vv['pv'] ? round($vv['rt'] / $vv['pv'], 5) : 0;
        //         return $vv;
        //     },
        //     $v['datetime']
        // );
        return $v;
    },
    $pathCount
);
switch ($type) {
    case 'dkw_sdk':
        descArr($pathCount, 'pv');
        break;

    default:
        if(empty($_GET['ip'])){
            descArr($pathCount, 'rt_avg');
            $pathCount = array_slice($pathCount, 0, 50);
        }else{
            descArr($pathCount, 'pv');
        }
        break;
}

// 执行时间分组
// $runtimeCount = array_map(
//     function ($v) {
//         descArr($v['datetime'], 'pv');
//         $v['datetime'] = array_slice($v['datetime'], 0, 5);
//         return $v;
//     },
//     $runtimeCount
// );
// 时间分组
$timeCount = array_map(
    function ($v) {
        // 统计平均执行时长
        $v['rt_avg'] = $v['pv'] ? round($v['rt'] / $v['pv'], 5) : 0;
        return $v;
    },
    $timeCount
);

// 时间分组的x轴
$timeXLable = json_encode(array_keys($timeCount));

// echo '<pre>';
// var_dump($pv, $uv, $ipCount, $pathCount, $runtimeCount, $timeCount);
// exit('_end');


function calculate($str){
    $cond = $GLOBALS['cond'];
    // 根据日志类型设置功能
    $action = array(); // ip，path，runtime，datetime
    switch ($GLOBALS['type']) {
        case 'dkw':
            $preg = "#^({$cond['ip']}).*?\[(.*?) \+.*?\].*?\"(.*?) ({$cond['path']}) .*?\"执行时间 (.*)\"#m";
            $action = array('ip', 'path', 'runtime', 'datetime');
            break;

        case 'dkw_sdk':
            $preg = "#^\"({$cond['ip']})\".*?\"(.*?) \+.*?\".*?\"(.*?) ({$cond['path']}) .*?#m";
            $action = array('ip', 'path', 'datetime'); // 没有运行时间
            break;

        default:
            $preg = "#^({$cond['ip']}).*?\[(.*?) \+.*?\].*?\"(.*?) ({$cond['path']}) .*?\"执行时间 (.*)\"#m";
            break;
    }
    // exit($preg);
    preg_match_all($preg, $str, $matches);
    // var_dump($matches);die;
    $GLOBALS['pv'] += count($matches[1]);

    // ip
    foreach ($matches[1] as $k => $v) {
        // 次数
        $GLOBALS['ipCount'][$v]['pv'] += 1;
        // 独立路径次数
        $path = $matches[4][$k];
        if(!isset($GLOBALS['ipCountData'][$v]['path'][$path])){
            $GLOBALS['ipCountData'][$v]['path'][$path] = ''; // 去重
            $GLOBALS['ipCount'][$v]['upv'] += 1;
        }
        // 总执行时长
        $GLOBALS['ipCount'][$v]['rt'] += $matches[5][$k];
        // // 时间
        // $date = datetimeFormat($matches[2][$k]);
        // // 时间区间的次数
        // $GLOBALS['ipCount'][$v]['datetime'][$date]['pv'] += 1;
        // // 时间区间的总执行时长
        // $GLOBALS['ipCount'][$v]['datetime'][$date]['rt'] += $matches[5][$k];
        // // 时间区间的独立路径次数
        // if(!isset($GLOBALS['ipCountData'][$v]['datetime'][$date][$path])){
        //     $GLOBALS['ipCountData'][$v]['datetime'][$date][$path] = '';
        //     $GLOBALS['ipCount'][$v]['datetime'][$date]['upv'] += 1;
        // }
    }
    // path
    foreach ($matches[4] as $k => $v) {
        switch ($GLOBALS['type']) {
            case 'dkw_sdk':
                if(strpos($v, '/payBack/') === 0){
                    $v = '/payBack/...';
                }
                if(strpos($v, '/notifyBack/') === 0){
                    $v = '/notifyBack/...';
                }
                if(strpos($v, '/sdkpay/index.php?a=success&') === 0){
                    $v = '/sdkpay/index.php?a=success&...';
                }
                if(strpos($v, '/sdkpay/index.php?a=error&') === 0){
                    $v = '/sdkpay/index.php?a=error&...';
                }
                if(strpos($v, '/sdkpay/index.php?m=index&a=sdkpay&') === 0){
                    $v = '/sdkpay/index.php?m=index&a=sdkpay&...';
                }
                if(strpos($v, '/sdkpay/index.php?a=sdkpay&') === 0){
                    $v = '/sdkpay/index.php?a=sdkpay&...';
                }
                if(strpos($v, '//mini_app/index.php?m=index&') === 0){
                    $v = '//mini_app/index.php?m=index&...';
                }
                if(strpos($v, '//sdkpay/index.php?a=sdkpay&m=index&h5_game=1&') === 0){
                    $v = '//sdkpay/index.php?a=sdkpay&m=index&h5_game=1&...';
                }
                if(strpos($v, '/mini_app/index.php?game=') === 0){
                    $v = '/mini_app/index.php?game=...';
                }
                if(strpos($v, '/sdkpay/index.php?a=sendGameGoods&') === 0){
                    $v = '/sdkpay/index.php?a=sendGameGoods&...';
                }
                break;
            
            default:
                # code...
                break;
        }

        // 次数
        $GLOBALS['pathCount'][$v]['pv'] += 1;
        // 独立ip次数
        $ip = $matches[1][$k];
        if(!isset($GLOBALS['pathCountData'][$v]['ip'][$ip])){
            $GLOBALS['pathCountData'][$v]['ip'][$ip] = ''; // 去重
            $GLOBALS['pathCount'][$v]['uv'] += 1;
        }
        // 总执行时长
        $GLOBALS['pathCount'][$v]['rt'] += $matches[5][$k];
        // // 时间
        // $date = datetimeFormat($matches[2][$k]);
        // // 时间区间的次数
        // $GLOBALS['pathCount'][$v]['datetime'][$date]['pv'] += 1;
        // // 时间区间的总执行时长
        // $GLOBALS['pathCount'][$v]['datetime'][$date]['rt'] += $matches[5][$k];
        // // 时间区间的独立路径次数
        // if(!isset($GLOBALS['pathCountData'][$v]['datetime'][$date][$ip])){
        //     $GLOBALS['pathCountData'][$v]['datetime'][$date][$ip] = '';
        //     $GLOBALS['pathCount'][$v]['datetime'][$date]['uv'] += 1;
        // }
    }
    // runtime
    if(in_array('runtime', $action)){
        foreach ($matches[5] as $k => $v) {
            // 次数
            $s = floor($v);
            if($s < 1){
                continue;
            }
            $s = $s > 20 ? '999' : $s;
            
            $GLOBALS['runtimeCount'][$s]['pv'] += 1;    
            // 独立ip次数
            $ip = $matches[1][$k];
            if(!isset($GLOBALS['runtimeCountData'][$s]['ip'][$ip])){
                $GLOBALS['runtimeCountData'][$s]['ip'][$ip] = ''; // 去重
                $GLOBALS['runtimeCount'][$s]['uv'] += 1;
            }
            // 独立路径次数
            $path = $matches[4][$k];
            if(!isset($GLOBALS['runtimeCountData'][$s]['path'][$path])){
                $GLOBALS['runtimeCountData'][$s]['path'][$path] = ''; // 去重
                $GLOBALS['runtimeCount'][$s]['upv'] += 1;
            }
            // // 时间
            // $date = datetimeFormat($matches[2][$k]);
            // // 时间区间的次数
            // $GLOBALS['runtimeCount'][$s]['datetime'][$date]['pv'] += 1;
            // // 时间区间的独立路径次数
            // if(!isset($GLOBALS['runtimeCountData'][$s]['datetime'][$date][$path])){
            //     $GLOBALS['runtimeCountData'][$s]['datetime'][$date][$path] = '';
            //     $GLOBALS['runtimeCount'][$s]['datetime'][$date]['upv'] += 1;
            // }
        }
    }
    // datetime
    foreach ($matches[2] as $k => $v) {
        $date = datetimeFormat($v);
        // 次数
        $GLOBALS['timeCount'][$date]['pv'] += 1;
        // 总执行时长
        $GLOBALS['timeCount'][$date]['rt'] += $matches[5][$k];
        // 独立ip次数
        $ip = $matches[1][$k];
        if(!isset($GLOBALS['timeCountData'][$date]['ip'][$ip])){
            $GLOBALS['timeCountData'][$date]['ip'][$ip] = ''; // 去重
            $GLOBALS['timeCount'][$date]['uv'] += 1;
        }
        // 独立路径次数
        $path = $matches[4][$k];
        if(!isset($GLOBALS['timeCountData'][$date]['path'][$path])){
            $GLOBALS['timeCountData'][$date]['path'][$path] = ''; // 去重
            $GLOBALS['timeCount'][$date]['upv'] += 1;
        }
    }
}

// 处理日志的时间格式
function datetimeFormat($time){
    preg_match('#^(\d{2})/([A-Z][a-z]{2})/(\d{4}):(\d{2}:\d{2}:\d{2})#', $time, $m);
    return date($GLOBALS['timeFormat'], strtotime("{$m[3]}-{$GLOBALS['monthMap'][$m[2]]}-{$m[1]} {$m[4]}"));
}
// 多维数组，指定字段倒序
function descArr(&$arr, $sortKey){
    uasort($arr, function ($a, $b) use ($sortKey) {
        $sortDesc = true;
        $c = $a[$sortKey] - $b[$sortKey];
        $c != 0 && ($c = $c > 0 ? 1 : -1);
        return $sortDesc ? -$c : $c; // 对比不能有小数
    });
}
// 转码路径成win格式
function sysPath($utf8Path){
    return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'
           ? iconv('UTF-8', 'GBK//IGNORE', $utf8Path)
           : $utf8Path;
}
// 查询ip归属地
function getIpAddr($ip)
{
    if(empty($ip)){
        return '空参数';
    }

    $url = "https://opendata.baidu.com/api.php?query={$ip}&co=&resource_id=6006&oe=utf8";
    $method = "GET";

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_FAILONERROR, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HEADER, false);
    if (1 == strpos("$".$url, "https://")) {
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    }

    $res = curl_exec($curl);
    curl_close($curl);
    $arr = json_decode($res, true);

    if(!isset($arr['data'][0]['location'])){
        return 'api返回错误';
    }

    return $arr['data'][0]['location'];
}
// 获取请求参数
function i($key, $type = 'get'){
    switch ($type) {
        case 'get':
            return isset($_GET[$key]) ? strip_tags(trim($_GET[$key])) : '';

        default:
            return '';
    }
}

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>nginx访问日志分析</title>
<style type="text/css">
    a{
        color: #0e72cc;
        text-decoration: underline #0e72cc;
    }
    p{
        margin: 10px 0;
    }
    .form-item{
        display: inline-block;
        padding: 5px;
        border: 1px solid #ccc;
    }
    .form-item input{
        padding: 5px;
    }
    .form-btn{
        display: inline-block;
        margin-top: 10px;
        padding: 6px 18px;
        border: none;
        border-radius: 5px;
        background: #1abc9c;
        color: #fff;
    }
    .title{
        text-align: center;
    }
    .bold{
        font-size: 18px;
        font-weight: bold;
    }
    .tb{
        border-collapse: collapse;
        word-break: break-word;
    }
    .tb th,
    .tb td{
        border: 1px solid #333;
        padding: 2px 8px;
    }

    .item{
        display: inline-block;
        width: <? echo $timeFormat == 'i' ? '49%' : '32%'?>;
    }
    
</style>

</head>
<body>
<div class="main">
    <p>说明：<span class="bold">pv</span>：每次请求计算1次 | <span class="bold">uv</span>：pv的基础上ip去重 | <span class="bold">upv</span>：pv的基础上访问路径去重 | <span class="bold">rt</span>：每个pv的执行时间累计秒数 | <span class="bold">rt_avg</span>：rt的平均数</p>
    <hr>

    <p>文件路径：<? echo "{$fileName} (大小：{$fileSize}MB) | 周" . date('N', strtotime($nowDate));?></p>
    <hr>
    <!--搜索-->
    <form action="<? echo '//', $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];?>">
        <input type="hidden" name="file_name" value="<? echo $_GET['file_name'];?>">
        <div class="form-item">
            时间：
            <input type="text" name="start_time" value="<? echo $_GET['start_time'];?>"
                   placeholder="时:分"
                   title="可用格式【时:分】【时 分】【时】"
                   style="width: 50px;"
                   autocomplete="off"> - 
            <input type="text" name="end_time" value="<? echo $_GET['end_time'];?>"
                   placeholder="时:分"
                   title="可用格式【时:分】【时 分】【时】"
                   style="width: 50px;"
                   autocomplete="off">
            <a class="js-reset-input" href="javascript:">清除</a>
        </div>
        <div class="form-item">
            ip：
            <input type="text" name="ip" value="<? echo $_GET['ip'];?>"
                   placeholder="完整ip"
                   style="width: 130px;"
                   autocomplete="off">
        </div>
        <div class="form-item">
            路径：
            <input type="text" name="path" value="<? echo $_GET['path'];?>"
                   placeholder="完整路径"
                   style="width: 500px;"
                   autocomplete="off">
        </div>
        <div>
            <button class="form-btn" type="submit">查询</button>
        </div>
    </form>
    <hr>

    <p><? echo 'pv：' . $pv . '；uv：' . $uv;?></p>
    <hr>
</div>

<? $canvasHeight = $timeFormat == 'i' ? 100 : 150;?>
<div class="main">
    <p>时间分组<? echo $timeFormat == 'i' ? '（分）' : '（时）';?></p>
    <div class="item">
        <canvas id="pv" height="<? echo $canvasHeight;?>"></canvas>
    </div>
    <div class="item">
        <canvas id="uv" height="<? echo $canvasHeight;?>"></canvas>
    </div>
    <div class="item">
        <canvas id="upv" height="<? echo $canvasHeight;?>"></canvas>
    </div>
    <div class="item">
        <canvas id="rt" height="<? echo $canvasHeight;?>"></canvas>
    </div>
    <div class="item">
        <canvas id="rtAvg" height="<? echo $canvasHeight;?>"></canvas>
    </div>
    
    <hr>
</div>

<div class="main">
    <p>ip分组，pv倒序</p>
    <table class="tb">
        <tr>
            <th>No</th>
            <th>ip</th>
            <th>pv</th>
            <th>upv</th>
            <th>rt_avg(秒)</th>
            <th>rt(秒)</th>
            <th>ip归属地</th>
        </tr>
        <?
            $i = 1;
            foreach($ipCount as $k => $v){
                echo '<tr>'
                    ,'<td>',$i++,'</td>'
                    ,"<td><a href='?file_name={$_GET['file_name']}&ip={$k}&type={$type}' target='_blank'>",$k,'</a></td>'
                    ,'<td>',$v['pv'],'</td>'
                    ,'<td>',$v['upv'],'</td>'
                    ,'<td>',$v['rt_avg'],'</td>'
                    ,'<td>',$v['rt'],'</td>'
                    ,'<td>',getIpAddr($k),'</td>'
                    ,'</tr>';
            }
        ?>
    </table>
    <hr>
</div>
<div class="main">
    <p>路径分组，rt_avg倒序</p>
    <table class="tb">
        <tr>
            <th>No</th>
            <th style="max-width: 800px;">path</th>
            <th>rt_avg(秒)</th>
            <th>pv</th>
            <th>uv</th>
            <th>rt(秒)</th>
        </tr>
        <?
            $i = 1;
            foreach($pathCount as $k => $v){
                $uk = urlencode($k);
                echo '<tr>'
                    ,'<td>',$i++,'</td>'
                    ,"<td style=\"max-width: 800px;\"><a href='?file_name={$_GET['file_name']}&path={$uk}&type={$type}' target='_blank'>",$k,'</a></td>'
                    ,'<td>',$v['rt_avg'],'</td>'
                    ,'<td>',$v['pv'],'</td>'
                    ,'<td>',$v['uv'],'</td>'
                    ,'<td>',$v['rt'],'</td>'
                    ,'</tr>';
            }
        ?>
    </table>
    <hr>
</div>

<div class="main">
    <p>运行时间分组，秒倒序</p>
    <table class="tb">
        <tr>
            <th>No</th>
            <th>秒</th>
            <th>pv</th>
            <th>uv</th>
            <th>upv</th>
        </tr>
        <?
            $i = 1;
            foreach($runtimeCount as $k => $v){
                echo '<tr>'
                    ,'<td>',$i++,'</td>'
                    ,'<td>',($k == 999 ? '20+' : $k),'</td>'
                    ,'<td>',$v['pv'],'</td>'
                    ,'<td>',$v['uv'],'</td>'
                    ,'<td>',$v['upv'],'</td>'
                    ,'</tr>';
            }
        ?>
    </table>
    <hr>
</div>

<script src="./static/jquery-3.6.1.min.js" type="text/javascript"></script>
<script src="./static/Chart.min.js" type="text/javascript"></script>
<script type="text/javascript">
    new Chart($('#pv')[0].getContext('2d'), {
        // 要创建的图表类型
        type: 'line'
        // 数据集
        ,data: {
            labels: JSON.parse('<? echo $timeXLable; ?>')
            ,datasets: [{
                label: 'pv：访问数'
                ,pointHitRadius: 8
                ,borderColor: '#3682be'
                ,background: 'transparent'
                ,data: JSON.parse('<? echo json_encode(array_column($timeCount, 'pv')); ?>')
            }]
            // #f8cb7f #76da91 #f8cb7f
        }

        // 配置选项
        ,animation: false
        ,options: {
            tooltips: {
                mode: 'point'
            }
        }
    });

    new Chart($('#uv')[0].getContext('2d'), {
        // 要创建的图表类型
        type: 'line'
        // 数据集
        ,data: {
            labels: JSON.parse('<? echo $timeXLable; ?>')
            ,datasets: [{
                label: 'uv：独立用户数'
                ,pointHitRadius: 8
                ,borderColor: '#45a776'
                ,background: 'transparent'
                ,data: JSON.parse('<? echo json_encode(array_column($timeCount, 'uv')); ?>')
            }]
            // #f8cb7f #76da91 #f8cb7f
        }

        // 配置选项
        ,animation: false
        ,options: {
            tooltips: {
                mode: 'point'
            }
        }
    });

    new Chart($('#upv')[0].getContext('2d'), {
        // 要创建的图表类型
        type: 'line'
        // 数据集
        ,data: {
            labels: JSON.parse('<? echo $timeXLable; ?>')
            ,datasets: [{
                label: 'upv：独立路径数'
                ,pointHitRadius: 8
                ,borderColor: '#f05326'
                ,background: 'transparent'
                ,data: JSON.parse('<? echo json_encode(array_column($timeCount, 'upv')); ?>')
            }]
            // #f8cb7f #76da91 #f8cb7f
        }

        // 配置选项
        ,animation: false
        ,options: {
            tooltips: {
                mode: 'point'
            }
        }
    });

    new Chart($('#rtAvg')[0].getContext('2d'), {
        // 要创建的图表类型
        type: 'line'
        // 数据集
        ,data: {
            labels: JSON.parse('<? echo $timeXLable; ?>')
            ,datasets: [{
                label: 'rt_avg：平均执行时间（秒）'
                ,pointHitRadius: 8
                ,borderColor: '#b3974e'
                ,background: 'transparent'
                ,data: JSON.parse('<? echo json_encode(array_column($timeCount, 'rt_avg')); ?>')
            }]
            // #f8cb7f #76da91 #f8cb7f
        }

        // 配置选项
        ,options: {
            tooltips: {
                mode: 'point'
            }
        }
    });

    new Chart($('#rt')[0].getContext('2d'), {
        // 要创建的图表类型
        type: 'line'
        // 数据集
        ,data: {
            labels: JSON.parse('<? echo $timeXLable; ?>')
            ,datasets: [{
                label: 'rt：累计执行时间（秒）'
                ,pointHitRadius: 8
                ,borderColor: '#334f65'
                ,background: 'transparent'
                ,data: JSON.parse('<? echo json_encode(array_column($timeCount, 'rt')); ?>')
            }]
            // #f8cb7f #76da91 #f8cb7f
        }

        // 配置选项
        ,options: {
            tooltips: {
                mode: 'point',
            }
        }
    });

    // 清除输入框
    $('.js-reset-input').on('click', function(){
        $(this).parent().find('input,select').val('');
    });
</script>
</body>
</html>
